/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package Tree;

import java.io.File;
import java.util.ArrayList;
import java.util.Enumeration;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

/**
 *
 * @author Alex
 */
public class DirTree extends JTree {

    
    //lấy đối tượng FileNode được gói trong 1 node DefaultMutableTreeNode
    public static FileNode getFileNode(DefaultMutableTreeNode node)
    {
        if (node == null)
        {
            return null;
        }

        Object obj = node.getUserObject();

        if (obj instanceof IconData)
        {
            obj = ((IconData) obj).getObject();
            if (obj instanceof FileNode)
            {
                return (FileNode) obj;
            }
        }
        return null;
    }   

    public static DefaultMutableTreeNode getTreeNode(TreePath path)
    {
        return (DefaultMutableTreeNode) (path.getLastPathComponent());
    }
    
    
    
    protected DefaultTreeModel _modelTree;
    
    
    /**
     *  Default constructor
     */
    public DirTree()
    {
        super();
        initTree();
    }
    
    
    private void initTree()
    {
        int index;
        DefaultMutableTreeNode top = new DefaultMutableTreeNode(new IconData(null, null, "My Computer"));
        DefaultMutableTreeNode node;
        
        File[] roots = File.listRoots();
        for (index = 0; index < roots.length; index++)
        {
            node = new DefaultMutableTreeNode(new IconData(null, null, new FileNode( roots[index]) ));
            top.add(node);
            
            // node has child
            node.add(new DefaultMutableTreeNode(new Boolean(true)));
        }
        
        _modelTree = new DefaultTreeModel(top);
        this.setModel(_modelTree);
        
        this.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        
        this.putClientProperty("JTree.lineStyle", "Angeled");
        
        this.setExpandsSelectedPaths(true);
        
        // Draw icon
//        TreeCellRenderer renderer = new IconCellRenderer();
//        this.setCellRenderer(renderer);
//        this.addTreeExpansionListener(new DirExpansionListener());        
//        this.setShowsRootHandles(true);
//        this.setEditable(false);
        
    }

    public void expandAtNode(File f)
    {        
        TreePath path;
        ArrayList<String> kq = new ArrayList<String>();

        while (f != null)
        {
//            FileNode fnode = new FileNode(f);
//            IconData data = new IconData(ICON_FOLDER, ICON_EXPANDEDFOLDER, fnode);
//            DefaultMutableTreeNode node = new DefaultMutableTreeNode(data);
            String temp = f.getName().length() > 0 ? f.getName() : f.getPath();
            kq.add(0, temp);
            f = f.getParentFile();
        }        
        kq.add(0, _modelTree.getRoot().toString());

        path = findByName(kq.toArray(new String[kq.size()]));
        
        //this.clearSelection();
        //this.addSelectionPath(path);

        this.setSelectionPath(path);
        this.expandPath(path);
        this.scrollPathToVisible(path);
    }

    //Tìm path của cây, từ mảng names
    public TreePath findByName(String[] names)
    {
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) this.getModel().getRoot();
        return find2(new TreePath(root), names, 0, true);
    }


    
    private TreePath find2(TreePath parent, Object[] nodes, int depth, boolean byName)
    {
        DefaultMutableTreeNode node = (DefaultMutableTreeNode) parent.getLastPathComponent();
        Object o = node;

        // If by name, convert node to a string
        if (byName)
        {
            o = o.toString();
        }

        // If equal, go down the branch
        //if (o.equals(nodes[depth]))
        if (o.equals(nodes[depth]))
        {
            // If at end, return match
            if (depth == nodes.length - 1)
            {
                return parent;
            }

            // Traverse children
            if (node.getChildCount() >= 0)
            {
                DefaultMutableTreeNode tn = (DefaultMutableTreeNode)node.getFirstChild();
                Object obj = tn.getUserObject();
                if (obj instanceof Boolean)//nếu chưa load các phần tử thì load lên
                {
                    final DefaultMutableTreeNode node_ = node;
                    final FileNode fnode = DirTree.getFileNode(node_);
                    if (fnode != null && fnode.expand(node_))
                    {
                        _modelTree.reload(node);
                    }
                }
                                
                    for (Enumeration e = node.children(); e.hasMoreElements();)
                    {
                        DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement();
                        TreePath path = parent.pathByAddingChild(n);
                        TreePath result = find2(path, nodes, depth + 1, byName);
                        // Found a match
                        if (result != null)
                        {
                            return result;
                        }
                    }                
            }
        }

        // No match at this branch
        return null;
    }
    
}
